using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using CapaAccesoDatos;
using CapaAccesoDatos.Clases;

namespace CapaNegocios
{
    // Esta clase Estacion representa las estaciones del laboratorio con todas sus propiedades propias, 
    // como son el ID, la Etiqueta, etc... y otras propiedades que necesita la aplicacion como son Cambiado,
    // Nueva, una lista con los horarios de ocupacion y un objeto aula que determina a que aula pertenece 
    // cada estacion.

    /// <summary>
    /// Representa las estaciones del laboratorio.
    /// </summary>
    public class Estacion
    {
        //---------- <Propiedades> ----------//
        /// <summary>
        /// ID de cada estacion en la base de datos.
        /// </summary>
        private int id;
        /// <summary>
        /// Numero fisico que tiene cada estacion en su respectiva aula.
        /// </summary>
        private string etiqueta;
        /// <summary>
        /// Indica si la estacion esta disponible en un intervalo de tiempo.
        /// </summary>
        private bool disponibilidad;
        /// <summary>
        /// Flag utilizado para discernir ciales objetos se insertaran/actualizaran en la base de datos
        /// al momento de, por ejemplo, utilizar el metodo Aula.Save(). 
        /// </summary>
        private bool cambiado;
        /// <summary>
        /// Lista que contiene todos los horarios en los que la estacion esta
        /// ocupada.
        /// </summary>
        private List<Horario> horariosDeOcupacion;
        /// <summary>
        /// Indica a que aula pertenece esta estacion.
        /// </summary>
        private Aula aula;

        //---------- </Propiedades> ----------//

        //---------- <Accesores> ----------//
        /// <summary>
        /// Obtiene el id de la estacion desde la base de datos.
        /// </summary>
        /// <value>int id.</value>
        public int ID
        {
            get { return this.id; }
        }
        /// <summary>
        /// Obtiene la etiqueta de la estacion desde la base de datos.
        /// </summary>
        /// <value>int etiqueta.</value>
        public string Etiqueta
        {
            get { return this.etiqueta; }
            //private set
            //{
            //    if (value <= this.aula.NoEstaciones && value > 0)
            //    {
            //        foreach (Estacion Estacion in this.aula.Estaciones)
            //        {
            //            if (value == Estacion.Etiqueta)
            //                throw new ArgumentException("Se ha producido una excepcion! Fijate si la etiqueta esta repetida");
            //        }
            //        this.etiqueta = value;
            //    }
            //    else throw new ArgumentException("Se ha producido una excepcion! Fijate si la etiqueta sobrepasa el numero de estaciones del aula a la que pertenece");
            //}
        }
        /// <summary>
        /// Obtiene un bool (True o False) indicando si la estacion esta disponible o no en un horario indicado.
        /// </summary>
        /// <value><c>true</c> si el aula esta disponible; de lo contrario, <c>false</c>.</value>
        public bool Disponibilidad
        {
            get { return this.disponibilidad; }
        }
        /// <summary>
        /// Obtiene un bool (True o False) indicando si la estacion debe insertarse/actualizarse en la base de datos o no.
        /// </summary>
        /// <value><c>true</c> si el aula ha sido cambiada; de lo contrario, <c>false</c>.</value>
        public bool Cambiado
        {
            get { return this.cambiado; }
        }
        /// <summary>
        /// Obtiene los horarios en los que la estacion esta ocupada desde la base de datos.
        /// </summary>
        /// <value>HorariosDeOcupacion.</value>
        public List<Horario> HorariosDeOcupacion
        {
            get
            {
                if (this.horariosDeOcupacion.Count == 0)
                {
                    foreach (HorarioCAD Item in AulaOcupadaCAD.GetHorariosDeOcupacion(this.Aula.ID))
                    {
                        Horario HorarioToAdd = new Horario(Item.HoraInicio, Item.HoraFin);
                        this.horariosDeOcupacion.Add(HorarioToAdd);
                    }
                    foreach (HorarioCAD Item in ReservacionCAD.GetHorariosDeOcupacion(this.id))
                    {
                        Horario HorarioToAdd = new Horario(Item.HoraInicio, Item.HoraFin);
                        this.horariosDeOcupacion.Add(HorarioToAdd);
                    }
                }
                return this.horariosDeOcupacion;
            }
        }
        /// <summary>
        /// Obtiene informacion desde la base de datos sobre a que aula pertenece la estacion.
        /// </summary>
        /// <value>Aula aula.</value>
        public Aula Aula
        {
            get
            {
                if (this.aula == null)
                {
                    this.aula = new Aula(EstacionCAD.BuscarPorId(this.id).Id_Aula);
                }
                return this.aula;
            }
        }

        //---------- </Accesores> ----------//

        //---------- <Constructores y demas metodos> ----------//
        // Constructor que recibe un id de una estacion como parametro que se encarga de inicializar cada 
        // estacion con toda la informacion que se encuentre en la base de datos.
        /// <summary>
        /// Inicializa una nueva instancia de la clase
        /// </summary>
        /// <param name="id">id del aula a instanciar.</param>
        internal Estacion(int id)
        {
            EstacionCAD EstacionRaw = EstacionCAD.BuscarPorId(id);

            this.id = EstacionRaw.Id;
            this.etiqueta = EstacionRaw.Etiqueta;
            this.disponibilidad = EstacionRaw.Disponibilidad;

            this.horariosDeOcupacion = new List<Horario>();
            this.aula = null;
        }
        // Constructor que recibe como parametro un objeto EstacionCAD y llena la informacion de la estacion
        // con la informacion contenida en este objeto.
        /// <summary>
        /// Inicializa una nueva instancia de la clase
        /// </summary>
        /// <param name="EstacionRaw">El objeto EstacionCAD a traves del cual se creara la nueva Estacion.</param>
        internal Estacion(EstacionCAD EstacionRaw)
        {
            this.id = EstacionRaw.Id;
            this.etiqueta = EstacionRaw.Etiqueta;
            this.disponibilidad = EstacionRaw.Disponibilidad;

            this.horariosDeOcupacion = new List<Horario>();
            this.aula = null;
        }

        /// <summary>
        /// Identifica la estacion a partir de los datos que llegan desde la capa grafica .
        /// </summary>
        /// <param name="CodigoAula">El codigo del aula.</param>
        /// <param name="EtiquetaEstacion">La etiqueta de la estacion.</param>
        /// <returns></returns>
        internal static Estacion IdentificarEstacion(string CodigoAula, string EtiquetaEstacion)
        {
            foreach (Estacion EstacionAInvestigar in new Aula(CodigoAula).Estaciones)
            {
                if (EstacionAInvestigar.Etiqueta.Trim() == EtiquetaEstacion)
                {
                    return EstacionAInvestigar;
                }
            }
            return null;
        }

        /// <summary>
        /// Comprueba si esta estacion esta disponible en el horario especificado.
        /// </summary>
        /// <remarks>
        /// Si un usuario ingresa un horario, aqui se verfica que 
        /// no ocurra choque con los horario previamente ocupados. Devuelve true o false, 
        /// dependiendo de las diversas razones por las cuales pueda ocurrir dicho evento 
        /// ya sea que haya clase en dicho horario o coincida con alguien que ya haya solicitado, etc.
        ///  </remarks>
        /// <param name="HorarioAInvestigar">El horario en el que se verificara la disponibilidad.</param>
        /// <returns>El valor de verdad de si hay disponibilidad o no en el horario.</returns>
        public bool DisponibilidadEnHorario(Horario HorarioAInvestigar)
        {
            foreach (Horario Intervalo in this.HorariosDeOcupacion)
            {
                if (Horario.HayChoque(Intervalo, HorarioAInvestigar) == true) return false;
            }
            return true;
        }

        /// <summary>
        /// Inserta una estacion en la base de datos.
        /// </summary>
        /// <param name="ObjectToSave">El objecto Estacion a insertar.</param>
        public static void Save(object ObjectToSave)
        {
            Estacion EstacionToSave = ObjectToSave as Estacion;

            EstacionCAD.Save(Estacion.MakeRaw(EstacionToSave));
        }
        /// <summary>
        /// Actualizar una estacion en la base de datos.
        /// </summary>
        /// <param name="ObjectToUpdate">El objecto Estacion a actualizar.</param>
        public static void Update(object ObjectToUpdate)
        {
            Estacion EstacionToUpdate = ObjectToUpdate as Estacion;

            EstacionCAD.Update(Estacion.MakeRaw(EstacionToUpdate));
        }
        /// <summary>
        /// Metodo que se encarga de eliminar una estacion en la base de datos.
        /// </summary>
        /// <param name="ObjectToDelete">El objecto Estacion a eliminar.</param>
        public static void Delete(object ObjectToDelete)
        {
            Estacion EstacionToDelete = ObjectToDelete as Estacion;

            EstacionCAD.Delete(Estacion.MakeRaw(EstacionToDelete));
        }

        /// <summary>
        /// Metodo que se utiliza para transformar un objeto de la Capa de Negocios a uno de la Capa de Acceso Datos
        /// para ser grabado, eliminado o actualizado en la base de datos.
        /// </summary>
        /// <param name="EstacionToMakeRaw">The estacion to make raw.</param>
        /// <returns></returns>
        public static EstacionCAD MakeRaw(Estacion EstacionToMakeRaw)
        {
            //EstacionCAD EstacionRaw;

            //EstacionRaw.Id = EstacionToMakeRaw.ID;
            //EstacionRaw.Etiqueta = EstacionToMakeRaw.Etiqueta.ToString();
            //EstacionRaw.Disponibilidad = EstacionToMakeRaw.Disponibilidad;

            //return EstacionRaw;

            return EstacionCAD.CrearEstacionCAD(EstacionToMakeRaw.ID,
                                                EstacionToMakeRaw.Etiqueta.ToString(),
                                                EstacionToMakeRaw.Aula.ID,
                                                String.Empty,
                                                EstacionToMakeRaw.Disponibilidad);
        }
        //---------- </Constructores y demas metodos> ----------//
    }
}
